# 代码功能说明：
# 这段代码演示了如何使用数值微分计算函数的导数
# 实现了中心差分法(numerical_diff)来计算导数
# 定义了一个示例函数function_1(x) = 0.01x² + 0.1x
# 在x=5处计算该函数的切线并绘制
# 最终显示原函数和在x=5处的切线
# 关键点：
# 中心差分法比前向差分法更精确
# 切线方程使用点斜式表示：y = f'(x0)(x-x0) + f(x0)
# 使用lambda函数方便地生成切线函数
# 可视化展示了函数在某点的切线斜率

# 指定文件编码为UTF-8
# coding: utf-8

# 导入NumPy数值计算库
import numpy as np

# 导入matplotlib的pylab绘图模块
import matplotlib.pylab as plt

# 定义数值微分函数
def numerical_diff(f, x):
    # 设置微小的增量h
    h = 1e-4 # 0.0001
    # 使用中心差分法计算导数
    return (f(x+h) - f(x-h)) / (2*h)

# 定义示例函数1
def function_1(x):
    # 二次函数示例：0.01x² + 0.1x
    return 0.01*x**2 + 0.1*x

# 定义切线函数
def tangent_line(f, x):
    # 计算函数在x点的导数
    d = numerical_diff(f, x)
    print(d)  # 打印导数值
    # 计算切线方程的截距
    y = f(x) - d*x
    # 返回切线函数
    return lambda t: d*t + y

# 生成x轴数据，从0.0到20.0，步长0.1
x = np.arange(0.0, 20.0, 0.1)
# 计算函数值
y = function_1(x)

# 设置x轴标签
plt.xlabel("x")
# 设置y轴标签
plt.ylabel("f(x)")

# 计算x=5处的切线
tf = tangent_line(function_1, 5)
# 计算切线上的点
y2 = tf(x)

# 绘制原函数曲线
plt.plot(x, y)
# 绘制切线
plt.plot(x, y2)
# 显示图形
plt.show()
